import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

extension RichTextExt on RichText {
  static List<TextSpan> createTextSpans({
    required String text,
    required List<String> actions,
    TextStyle? style,
    TextStyle? linkStyle,
    String prefix = '_&t',
    String suffix = '_&t',
    void Function(String action)? onLink,
  }) {
    final pattern = actions.map((e) => RegExp.escape(e)).join('|');
    final regExp = RegExp(pattern, multiLine: true);
    final textView = text.splitMapJoin(regExp,
        onMatch: (m) => '$prefix${m[0]}$suffix', onNonMatch: (n) => n);
    final list = textView.split(RegExp('$prefix|$suffix'));
    return list.map(
      (e) {
        if (e.isNotEmpty) {
          final isEqual = actions.contains(e);
          if (isEqual) {
            return TextSpan(
                text: e,
                style: linkStyle ?? const TextStyle(color: Colors.blue),
                recognizer: TapGestureRecognizer()
                  ..onTap = () {
                    onLink?.call(e);
                  });
          }
        }
        return TextSpan(text: e, style: style);
      },
    ).toList();
  }
}

extension LinkExt on Text {
  RichText toLink() {
    return RichText(
      text: TextSpan(
        children: RichTextExt.createTextSpans(text: data ?? '', actions: []),
      ),
    );
  }
}

extension TextEx on Text {
  RichText urlToLink(
    BuildContext context,
  ) {
    final textSpans = <InlineSpan>[];
    RegExp _urlReg = RegExp(
      r'https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=#]*)?',
    );
    data!.splitMapJoin(
      _urlReg,
      onMatch: (Match match) {
        final _match = match[0] ?? '';
        textSpans.add(
          TextSpan(
            text: _match,
            style: const TextStyle(
              color: Colors.blue,
              decoration: TextDecoration.underline,
            ),
            recognizer: TapGestureRecognizer()..onTap = () async {},
          ),
        );
        return '';
      },
      onNonMatch: (String text) {
        textSpans.add(
          TextSpan(
            text: text,
            style: const TextStyle(
              color: Colors.black,
            ),
          ),
        );
        return '';
      },
    );

    return RichText(text: TextSpan(children: textSpans));
  }
}
